/*
 * ========================================
 * RISC-V 最小操作系统内存布局定义
 * ========================================
 * 
 * 这个文件定义了QEMU virt平台的内存布局和设备地址映射。
 * 了解内存布局对于操作系统开发非常重要，因为我们需要知道：
 * - 内核代码放在哪里
 * - 设备寄存器在哪个地址
 * - 可用内存的范围
 * 
 * QEMU virt平台内存布局：
 * - 0x00001000 - 0x02000000: 引导ROM和设备
 * - 0x02000000 - 0x0C000000: CLINT (Core Local Interruptor)
 * - 0x0C000000 - 0x10000000: PLIC (Platform Level Interrupt Controller)  
 * - 0x10000000 - 0x10001000: UART0 串口设备
 * - 0x80000000 - 0xFFFFFFFF: 内核和用户内存空间
 */

#ifndef MEMLAYOUT_H
#define MEMLAYOUT_H

// ========================================
// 设备地址定义
// ========================================

// UART0 串口设备基地址
// UART (Universal Asynchronous Receiver/Transmitter) 是串行通信设备
// 在QEMU中，UART连接到虚拟终端，我们可以通过它输出文本
// 地址范围：0x10000000 - 0x10001000
#define UART0 0x10000000L

// ========================================
// 内存空间定义  
// ========================================

// 内核起始地址
// QEMU会将内核加载到这个地址，然后跳转执行
// 这是整个操作系统的入口点
#define KERNBASE 0x80000000L

// 物理内存结束地址
// 定义内核可以使用的最大物理内存地址
// 128MB对于最小操作系统来说已经足够
#define PHYSTOP (KERNBASE + 128*1024*1024)

// ========================================
// 内存管理相关定义
// ========================================

// 页大小定义
#define PGSIZE          4096        // 页大小：4KB
#define PGSHIFT         12          // 页大小位移：2^12 = 4096
#define PGMASK          (PGSIZE-1)  // 页掩码：0xFFF

// 内存对齐宏
#define PGROUNDUP(sz)   (((sz)+PGSIZE-1) & ~PGMASK)  // 向上对齐到页边界
#define PGROUNDDOWN(a)  (((a)) & ~PGMASK)            // 向下对齐到页边界

// 内核栈相关
#define KSTACKSIZE      4096        // 内核栈大小
#define KSTACKPAGE      1           // 内核栈页数

// 内存分配器相关
#define HEAP_START      (KERNBASE + 0x100000)  // 堆起始地址
#define HEAP_SIZE       (64*1024*1024)         // 堆大小：64MB

// 页表相关（注释掉，避免与riscv.h重复定义）
// #define MAXVA           (1L << 38)  // 最大虚拟地址（简化版）

#endif // MEMLAYOUT_H
